﻿// Copyright (c) 2014 Converter Systems LLC

using Opc.Ua;
using System;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.ServiceModel.Configuration;
using System.Collections.Generic;

namespace ConverterSystems.TestServer
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            try
            {
                var appConfig = new ApplicationConfiguration()
                {
                    ApplicationName = "ConverterSystems.TestServer",
                    ApplicationType = ApplicationType.Server,
                    SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier { StoreType = @"Windows", StorePath = @"CurrentUser\My", SubjectName = Utils.Format(@"CN={0}, DC={1}", "ConverterSystems.TestServer", System.Net.Dns.GetHostName()) }, TrustedPeerCertificates = new CertificateTrustList { StoreType = @"Windows", StorePath = @"CurrentUser\TrustedPeople", }, NonceLength = 32, AutoAcceptUntrustedCertificates = true },
                    TransportConfigurations = new TransportConfigurationCollection(),
                    TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
                    ServerConfiguration = new ServerConfiguration { SecurityPolicies = { new ServerSecurityPolicy { SecurityLevel = 0, SecurityMode = MessageSecurityMode.None, SecurityPolicyUri = SecurityPolicies.None }, new ServerSecurityPolicy { SecurityLevel = 1, SecurityMode = MessageSecurityMode.SignAndEncrypt, SecurityPolicyUri = SecurityPolicies.Basic128Rsa15 }, new ServerSecurityPolicy { SecurityLevel = 2, SecurityMode = MessageSecurityMode.SignAndEncrypt, SecurityPolicyUri = SecurityPolicies.Basic256 } } }
                };
                appConfig.ServerConfiguration.BaseAddresses.AddRange(
                    ConfigurationManager.AppSettings.AllKeys
                    .Where(k => k.StartsWith("baseAddress"))
                    .Select(k => ConfigurationManager.AppSettings[k]));
                appConfig.ServerConfiguration.BaseAddresses = appConfig.ServerConfiguration.BaseAddresses.Select(s =>
                {
                    var uri = new UriBuilder(s);
                    if (string.Equals(uri.Host, "localhost", StringComparison.OrdinalIgnoreCase))
                    {
                        uri.Host = Dns.GetHostName();
                    }
                    return uri.ToString();
                }).ToArray();
                appConfig.Validate(ApplicationType.Server);
                appConfig.CertificateValidator.CertificateValidation += (s, e) => { if (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted) e.Accept = true; };
                appConfig.EnsureApplicationCertificate();
                var server = new Server();
                server.Start(appConfig);
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey(true);
            }
            catch (SocketException)
            {
                Console.WriteLine("A Server at this address is already running.");
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey(true);
            }
            catch (Exception ex)
            {
                Console.WriteLine("An exception occurred. {0}", ex.Message);
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey(true);
            }
        }

    }
}